﻿using Module = MicroCloud.Authorization.Entities.Module;

namespace MicroCloud.Authorization.Database
{
    #region "模块种子数据初始值设定项"
    /// <summary>
    /// 模块种子数据初始值设定项
    /// </summary>
    [Description("根节点模块种子数据")]
    public class ModuleSeedDataInitializer : SeedDataInitializerBase<Module, long>
    {
        #region "构造函数"
        #region "初始化一个模块种子数据初始值设定项的新实例"
        /// <summary>
        /// 初始化一个模块种子数据初始值设定项 <see cref="ModuleSeedDataInitializer"/> 的新实例
        /// </summary>
        /// <param name="rootProvider"></param>
        public ModuleSeedDataInitializer(IServiceProvider rootProvider)
            : base(rootProvider)
        { }
        #endregion

        #endregion

        #region "方法"
        #region "重写以提供要初始化的种子数据"
        /// <summary>
        /// 重写以提供要初始化的种子数据
        /// </summary>
        /// <param name="provider">服务提供者</param>
        /// <returns></returns>
        protected override Module[] SeedData(IServiceProvider provider)
        {
            return new[]
            {
                new Module() { Name = "根节点", FullName = "根节点", Remark = "系统根节点", Code = "Root", FullCode = "Root", OrderNo = 1 },
            };
        }
        #endregion
        #region "重写以提供判断某个实体是否存在的表达式"
        /// <summary>
        /// 重写以提供判断某个实体是否存在的表达式
        /// </summary>
        /// <param name="entity">要判断的实体</param>
        /// <returns></returns>
        protected override Expression<Func<Module, bool>> ExistingExpression(Module entity)
        {
            return m => m.Code.ToLower().Equals("root");
        }
        #endregion

        #region "将种子数据初始化到数据库"
        /// <summary>
        /// 将种子数据初始化到数据库
        /// </summary>
        /// <param name="entities">实体对象数组</param>
        /// <param name="provider">服务提供者</param>
        protected override void SyncToDatabase(Module[] entities, IServiceProvider provider)
        {
            if (entities == null || entities.Length == 0)
            {
                return;
            }

            provider.BeginUnitOfWorkTransaction(provider =>
            {
                IRepository<Module, long> repository = provider.GetService<IRepository<Module, long>>();
                foreach (var entity in entities)
                {
                    if (repository.CheckExists(ExistingExpression(entity)))
                    {
                        continue;
                    }

                    //父模块检查
                    string parentTreePathString = null;
                    if (entity.ParentId != null && entity.ParentId > 0)
                    {
                        var parent = repository.QueryAsNoTracking().Where(m => m.Id.Equals(entity.ParentId)).Select(m => new { m.Id, m.TreePathString }).FirstOrDefault() ?? throw new Exception(I18N.T("模块 {0} 不存在", entity.ParentId));
                        entity.ParentId = entity.ParentId;
                        parentTreePathString = parent.TreePathString;
                    }
                    else
                    {
                        entity.ParentId = null;
                    }
                    //持久化实体数据
                    var result = repository.Insert(entity);
                    if (result.Succeeded)
                    {
                        entity.TreePathString = entity.ParentId == null ? TreeHelper.FormatTreePathString(entity.Id) : TreeHelper.GetTreePathString(entity.Id, parentTreePathString);
                        repository.Update(entity);
                    }

                }
            });
        }
        #endregion

        #endregion

    }
    #endregion

}
